package blackstar.plugin.performance.stat;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import blackstar.agent.AgentConfig;
import blackstar.agent.event.EventDispatcherSupport;
import blackstar.agent.event.EventListener;
import blackstar.agent.event.StartupEvent;
import blackstar.agent.jmx.MBeanUtils;
import blackstar.agent.schedule.ScheduleEvent;
import blackstar.agent.schedule.ScheduleTask;

/**
 * @author RayWoo (ayufox@gmail.com)
 * 
 */
public class SimpleStat extends EventDispatcherSupport implements
		EventListener<StartupEvent>, SimpleStatMBean
{
	private final static String MBEAN_TYPE = "Performance";
	private final static String MBEAN_NAME = "SimpleStat";

	public final static Log LOGGER = LogFactory.getLog(SimpleStat.class);

	private String cronExpression = "4 0 2 * * ?";
	private ThreadHoldConfig threadHoldConfig = new ThreadHoldConfig(
			"10,50,100,300,500,1000,3000");

	public void setThreadHolds(String threadholds)
	{
		this.threadHoldConfig = new ThreadHoldConfig(threadholds);
	}

	public void setCronExpression(String cronExpression)
	{
		this.cronExpression = cronExpression;
	}

	public String statCurrentHour(String jvmid)
	{
		SimpleDateFormat dayFormat = new SimpleDateFormat("yyyyMMdd");
		SimpleDateFormat hourFormat = new SimpleDateFormat("HH");
		Date now = new Date();
		File file = new File(AgentConfig.getPerformanceLogPath(jvmid)
				+ File.separator + dayFormat.format(now) + File.separator
				+ "simple" + hourFormat.format(now) + ".log");
		if (file.exists())
		{
			SimpleStater stater = new SimpleStater(this.threadHoldConfig);
			try
			{
					stater.add(file);
			} catch (Exception e)
			{
				LOGGER.error("error when read from performance files", e);
				return "error when read from performance file:"
						+ e.getMessage();
			}
			String resultFile = AgentConfig.getPerformanceDataPath(jvmid)
					+ File.separator + "simple-" + dayFormat.format(now);

			try
			{
				stater.genToFile(new File(resultFile));
			} catch (Exception e)
			{
				LOGGER.error("error when read from performance files", e);
				return "error when gen performance result to file:"
						+ e.getMessage();
			}
			return "success";

		}
		else
		{
			LOGGER.info("stat file[" + file.getAbsolutePath() + "] not exits");
			return "no stat files";
		}
	}

	public String stat(String jvmid, String date)
	{
		// 性能数据目录
		String reportDir = AgentConfig.getPerformanceLogPath(jvmid)
				+ File.separator + date;
		File dir = new File(reportDir);
		if (!dir.exists())
		{
			return "report dir [" + reportDir + "] not exists";
		}

		if (!dir.isDirectory())
		{
			return "report dir [" + reportDir + "] is not directory";
		}

		File[] files = dir.listFiles(new FileFilter()
		{
			public boolean accept(File pathname)
			{
				return pathname.getName().startsWith("simple");
			}
		});

		if (files.length > 0)
		{
			SimpleStater stater = new SimpleStater(this.threadHoldConfig);
			try
			{
				for (File file : files)
				{
					stater.add(file);
				}
			} catch (IOException e)
			{
				return "error when read from performance files:"
						+ e.getMessage();
			}
			String resultFile = AgentConfig.getPerformanceDataPath(jvmid)
					+ File.separator + "simple-" + date;

			try
			{
				stater.genToFile(new File(resultFile));
			} catch (IOException e)
			{
				return "error when gen performance result to file:"
						+ e.getMessage();
			}

			return "success";
		}
		else
		{
			LOGGER.info("no stat files for dir[" + reportDir + "]");
			return "no stat files";
		}
	}

	public void stat()
	{
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.DAY_OF_MONTH, -1);
		String date = new SimpleDateFormat("yyyyMMdd").format(calendar
				.getTime());

		stat(date);
	}

	public void stat(String date)
	{
		LOGGER.info("Start Performance Stat:" + date);

		String result = null;
		File reportPath = new File(AgentConfig.getLogPath());
		if (reportPath.exists() && reportPath.isDirectory())
		{
			for (File dir : reportPath.listFiles())
			{
				LOGGER.info("Performance Stat[" + dir.getName() + "]");

				result = stat(dir.getName(), date);

				LOGGER.info("Performance Stat[" + dir.getName() + "] Result ["
						+ result + "]");
			}

			LOGGER.info("Performance Stat Success!");
		} else
		{
			LOGGER.warn("report path[" + reportPath.getAbsolutePath()
					+ "] not exist");
		}
	}

	public Class[] events()
	{
		return new Class[]
		{ StartupEvent.class };
	}

	public void onEvent(StartupEvent event) throws Exception
	{
		MBeanUtils.registMBean(MBEAN_NAME, MBEAN_TYPE, this);
		dispatch(new ScheduleEvent(this.cronExpression, new ScheduleTask()
		{
			public void schedule()
			{
				stat();
			}
		}));
	}
}
